package com.dimples.system.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dimples.common.constant.StrPool;
import com.dimples.common.entity.SecurityUser;
import com.dimples.common.exception.DataException;
import com.dimples.common.page.metadata.Page;
import com.dimples.common.service.DimplesJwtTokenServiceImpl;
import com.dimples.common.transport.QueryRequest;
import com.dimples.common.util.HttpContextUtil;
import com.dimples.common.util.SecurityContextUtil;
import com.dimples.system.entity.SysRole;
import com.dimples.system.entity.SysRoleMenu;
import com.dimples.system.entity.SysUserRole;
import com.dimples.system.mapper.SysRoleMapper;
import com.dimples.system.service.SysMenuService;
import com.dimples.system.service.SysRoleMenuService;
import com.dimples.system.service.SysRoleService;
import com.dimples.system.service.SysUserRoleService;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;

/**
 * @author zhongyj <1126834403@qq.com><br/>
 * @date 2021/7/4
 */
@Service
@RequiredArgsConstructor
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    private final SysRoleMenuService sysRoleMenuService;
    private final SysUserRoleService sysUserRoleService;
    private final SysMenuService sysMenuService;
    private final DimplesJwtTokenServiceImpl tokenService;

    @Override
    public Page<SysRole> findRole(SysRole sysRole, QueryRequest queryRequest) {
        Page<SysRole> page = new Page<>(queryRequest.getPageNumber(), queryRequest.getPageSize());
        page.setRecords(this.baseMapper.findRole(page, sysRole));
        return page;
    }

    @Override
    public SysRole findRoleById(Long roleId) {
        return this.getById(roleId);
    }

    @Override
    public void saveRole(SysRole sysRole) {
        sysRole.setCreateTime(new Date());
        this.save(sysRole);
    }

    @Override
    public void updateRole(SysRole sysRole) {
        SysRole byId = this.getById(sysRole.getRoleId());
        if (ObjectUtil.isEmpty(byId)) {
            throw new DataException(StrUtil.format("【roleId = {}】不存在", sysRole.getRoleId()));
        }
        sysRole.setModifyTime(new Date());
        this.updateById(sysRole);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteRole(Long roleId) {
        if (ObjectUtil.isEmpty(this.getById(roleId))) {
            throw new DataException(StrUtil.format("【roleId = {}】不存在", roleId));
        }
        this.sysRoleMenuService.remove(Wrappers.lambdaUpdate(SysRoleMenu.class).eq(SysRoleMenu::getRoleId, roleId));
        this.sysUserRoleService.remove(Wrappers.lambdaUpdate(SysUserRole.class).eq(SysUserRole::getRoleId, roleId));
        this.removeById(roleId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteRoles(String roleIds) {
        long[] roles = StrUtil.splitToLong(roleIds, StrPool.COMMA);
        for (long id : roles) {
            deleteRole(id);
        }
    }

    @Override
    public void bindRoleMenu(SysRoleMenu sysRoleMenu) {
        this.sysRoleMenuService.remove(Wrappers.lambdaUpdate(SysRoleMenu.class).eq(SysRoleMenu::getRoleId, sysRoleMenu.getRoleId()));
        List<SysRoleMenu> data = CollUtil.newArrayList();
        for (Long menuId : sysRoleMenu.getMenuIds()) {
            SysRoleMenu roleMenu = new SysRoleMenu();
            roleMenu.setMenuId(menuId);
            roleMenu.setRoleId(sysRoleMenu.getRoleId());
            if (ObjectUtil.isEmpty(this.sysRoleMenuService.getOne(Wrappers.lambdaUpdate(SysRoleMenu.class)
                    .eq(SysRoleMenu::getRoleId, sysRoleMenu.getRoleId()).eq(SysRoleMenu::getMenuId, menuId)))) {
                data.add(roleMenu);
            }
        }
        this.sysRoleMenuService.saveBatch(data);
        // 刷新token中的权限缓存
        String roleCode = this.getById(sysRoleMenu.getRoleId()).getRoleCode();
        List<String> roleCodes = tokenService.getLoginUserFromToken(HttpContextUtil.getRequest()).getRoleCodes();
        if (CollUtil.contains(roleCodes, roleCode)) {
            SecurityUser securityUser = new SecurityUser();
            Set<String> permissions = new HashSet<>(this.sysMenuService.findUserPermissions(tokenService.getUsernameFromToken(HttpContextUtil.getRequest())));
            securityUser.setAuthorities(permissions);
            SecurityContextUtil.refreshCache(tokenService, securityUser);
        }
    }

    @Override
    public List<SysRole> findRoleByUserId(Long userId) {
        return this.baseMapper.findRoleByUserId(userId);
    }
}



























